package com.maixy.studyonlineapi.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.google.common.collect.Lists;
import com.maixy.studyonlineapi.bean.Page;
import com.maixy.studyonlineapi.entity.TeamUser;
import com.maixy.studyonlineapi.entity.User;
import com.maixy.studyonlineapi.exceptions.TipException;
import com.maixy.studyonlineapi.mapper.TeamUserMapper;
import com.maixy.studyonlineapi.result.PageData;
import com.maixy.studyonlineapi.utils.LocalDateTimeUtils;
import com.maixy.studyonlineapi.view.TeamUserView;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;

/**
 * @Classname TeamUserService
 * @Description TODO
 * @Date 2020/11/1 19:37
 * @Author by maixy
 */
@Service
public class TeamUserService extends BaseMPlusService<TeamUser, Long> {
    private final TeamUserMapper teamUserMapper;

    @Resource
    private UserService userService;
    @Resource
    private TeamService teamService;

    protected TeamUserService(TeamUserMapper teamUserMapper) {
        super(TeamUser.class, teamUserMapper);
        this.teamUserMapper = teamUserMapper;
    }

    /**
     * huo获得团队成员列表
     *
     * @param teamId 团队id
     * @param page   页面信息
     * @return PageData<com.maixy.studyonlineapi.view.TeamUserView>
     */
    public PageData<TeamUserView> getTeamUserList(Long teamId, Page page) {
        page.setHasMore(false);
        PageData<TeamUserView> pageData = new PageData<>();
        pageData.setPage(page);
        pageData.setData(Collections.emptyList());
        int beginIndex = (page.getPage() - 1) * page.getSize();
        List<TeamUser> teamUserList = teamUserMapper.getTeamUserList(teamId, beginIndex, page.getSize() + 1);
        if (CollectionUtils.isEmpty(teamUserList)) {
            return pageData;
        }
        if (teamUserList.size() > page.getSize()) {
            page.setHasMore(true);
            teamUserList.remove(teamUserList.size() - 1);
        }
        List<TeamUserView> teamUserViewList = Lists.newArrayList();
        for (TeamUser teamUser : teamUserList) {
            teamUserViewList.add(convert(teamUser));
        }
        pageData.setData(teamUserViewList);
        return pageData;
    }

    /**
     * 团队成员视图
     *
     * @param teamUser 团队成员实体
     * @return com.maixy.studyonlineapi.view.TeamUserView
     */
    private TeamUserView convert(TeamUser teamUser) {
        TeamUserView view = new TeamUserView();
        User user = userService.findById(teamUser.getUserId());
        if (null == user || user.getHasDelete()) {
            throw new TipException("用户不存在或已被删除");
        }
        view.setUserView(userService.convert(user));
        view.setCreateTimeStr(LocalDateTimeUtils.format(teamUser.getCreateTime(), LocalDateTimeUtils.NORMAL_DATETIME_FORMAT_NO_SECOND));
        return view;
    }

    /**
     * 踢出团队成员
     *
     * @param teamId        团队id
     * @param userId        用户id
     * @param currentUserId 当前用户id
     */
    public void kickOut(Long teamId, Long userId, Long currentUserId) {
        if (!teamService.isSuperManager(teamId, userId)) {
            throw new TipException("只有超级管理员才能踢人");
        }

        TeamUser teamUser = findTeamUserByUserIdAndTeamId(teamId, currentUserId);
        if (null == teamUser || teamUser.getHasDelete()) {
            throw new TipException("找不到团队成员");
        }
        teamUser.setHasDelete(true);
        teamUser.setUpdateBy(userId);
        teamUser.setUpdateTime(System.currentTimeMillis());
        update(teamUser);
    }

    /**
     * 主动推出团队
     *
     * @param teamId 团队id
     * @param userId 用户id
     */
    public void quit(Long teamId, Long userId, Long quitTeamId) {
        if (teamId.equals(quitTeamId)) {
            throw new TipException("不能退出当前您所在的团队");
        }

        if (teamService.isSuperManager(quitTeamId, userId)) {
            throw new TipException("不能退出自己创建的团队");
        }


        TeamUser teamUser = findTeamUserByUserIdAndTeamId(quitTeamId, userId);
        if (null == teamUser || teamUser.getHasDelete()) {
            throw new TipException("找不到此团队成员或已被删除");
        } else {
            teamUser.setHasDelete(true);
            teamUser.setUpdateBy(userId);
            teamUser.setUpdateTime(System.currentTimeMillis());
            update(teamUser);
        }
    }

    /**
     * 查找某个用户是否在某个团队
     *
     * @param teamId 团队id
     * @param userId 用户id
     * @return com.maixy.studyonlineapi.entity.TeamUser
     */
    public TeamUser findTeamUserByUserIdAndTeamId(Long teamId, Long userId) {
        return teamUserMapper.selectOne(new QueryWrapper<TeamUser>()
                .lambda()
                .eq(TeamUser::getTeamId, teamId)
                .eq(TeamUser::getUserId, userId)
                .eq(TeamUser::getHasDelete, false)
                .orderByDesc(TeamUser::getCreateTime)
                .last("limit 1"));
    }

    /**
     * 添加团队成员
     *
     * @param teamId 团队id
     * @param userId 用户id
     * @return com.maixy.studyonlineapi.entity.TeamUser
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public TeamUser saveTeamUser(Long teamId, Long userId) {
        TeamUser teamUser = new TeamUser();
        teamUser.setTeamId(teamId);
        teamUser.setUserId(userId);
        teamUser.setCreateTime(System.currentTimeMillis());
        teamUser.setCreateBy(userId);
        teamUser.setHasDelete(false);
        create(teamUser);
        return teamUser;
    }

    /**
     * 根据用户查找已加入的团队
     *
     * @param userId 当前用户id
     * @return List<com.maixy.studyonlineapi.entity.TeamUser>
     */
    public List<TeamUser> findTeamUserListByUserId(Long userId) {
        return teamUserMapper.selectList(new QueryWrapper<TeamUser>()
                .lambda()
                .eq(TeamUser::getUserId, userId)
                .eq(TeamUser::getHasDelete, false));
    }

    public Integer countTeamUser(Long teamId) {
        return teamUserMapper.selectCount(new QueryWrapper<TeamUser>()
                .lambda()
                .eq(TeamUser::getTeamId, teamId)
                .eq(TeamUser::getHasDelete, false));
    }
}
